#include <ESP8266WiFi.h>
#include <PubSubClient.h>
#include <DHT.h>

const char* ssid = "601A";          // Replace with your WiFi SSID
const char* password = "12345678";  // Replace with your WiFi password

const char* mqtt_server = "bemfa.com";
const int mqtt_server_port = 9501;
#define ID_MQTT "1b79dfa058454105be487a4d510ac5aa"

WiFiClient espClient;
PubSubClient client(espClient);

#define TrigPin 4
#define EchoPin 5
#define BEEPin 15
#define DHTPIN 2
#define DHTTYPE DHT11
DHT dht(DHTPIN, DHTTYPE);

float distance;
const char* mqtt_temp_topic = "IOT_RECE";
const char* mqtt_hum_topic = "humidtopic";
const char* mqtt_air_topic = "airQualtopic";
const char* mqtt_light_topic = "lighttopic";
const char* mqtt_smoke_topic = "smoketopic";

void reconnect() {
  while (!client.connected()) {
    Serial.print("尝试连接MQTT...");
    if (client.connect(ID_MQTT)) {
      Serial.println("connected");
    } else {
      Serial.print("failed, rc=");
      Serial.print(client.state());
      Serial.println(" try again in 5 seconds");
      delay(5000);
    }
  }
}

void setup_wifi() {
  delay(10);
  Serial.println();
  Serial.print("Connecting to ");
  Serial.println(ssid);

  WiFi.begin(ssid, password);

  while (WiFi.status() != WL_CONNECTED) {
    delay(500);
    Serial.print(".");
  }

  Serial.println("");
  Serial.println("WiFi connected");
  Serial.print("IP address: ");
  Serial.println(WiFi.localIP());
}

void setup() {
  pinMode(BEEPin,OUTPUT);
  digitalWrite(BEEPin, HIGH);
  dht.begin();
  Serial.begin(115200);
  setup_wifi();
  client.setServer(mqtt_server, mqtt_server_port);
  reconnect();
}

void loop() {
  if (!client.connected()) {
    reconnect();
  }
  iot_temp();
  iot_monitor();
}

void iot_monitor() {
  float t = checkDistance();;
  // 发布光敏检测模拟量
  if (client.connected()) {
    String tempMsg = String(t);  
    Serial.print("将要发布的数据: ");
    Serial.println(tempMsg);
    client.publish(mqtt_light_topic, tempMsg.c_str());
    Serial.println("已发布模拟数据到MQTT");
  }
  skip();
}

void iot_temp() {
  float h = dht.readHumidity();
  float t = dht.readTemperature();

  // 检查传感器读数是否有效
  if (isnan(h) || isnan(t)) {
    Serial.println(F("Failed to read from DHT sensor!"));
    return;
  }

  Serial.print("湿度: ");
  Serial.println(h);
  Serial.print("温度: ");
  Serial.println(t);

  // 发布温度和湿度到MQTT
  if (client.connected()) {
    String tempMsg = String(t);
    String humidMsg = String(h);
    Serial.print("将要发布的温度: ");
    Serial.println(tempMsg);
    Serial.print("将要发布的湿度: ");
    Serial.println(humidMsg);

    client.publish(mqtt_temp_topic, tempMsg.c_str());
    client.publish(mqtt_hum_topic, humidMsg.c_str());
    Serial.println("已发布温度和湿度到MQTT");
  }
  if (t > 28) {
    String p_on = "on";
    client.publish("ledtopic", p_on.c_str());
    Serial.println("发布开启LED灯的状态");
  } else {
    String p_off = "off";
    client.publish("ledtopic", p_off.c_str());
    Serial.println("发布关闭LED灯的状态");
  }
  skip();
}

float checkDistance() {
  digitalWrite(TrigPin, LOW);
  delayMicroseconds(2);
  digitalWrite(TrigPin, HIGH);
  delayMicroseconds(10);
  digitalWrite(TrigPin, LOW);
  // 计算回声
  long duration = pulseIn(EchoPin, HIGH);
  // 通过回声计算距离
  distance = duration * 0.034 / 2;
  Serial.print(F("current length:"));
  Serial.print(distance);
  Serial.println(F("cm"));
  Serial.println();
  if (distance < 10) {
    bee();
  }
  delay(200);
  return distance; 
}

void skip() {
  for(int i=0;i<50;i++) {
    Serial.print("-");
  }
  delay(2500);  // 等待2秒
}
void bee() {
  digitalWrite(BEEPin, LOW);
  delay(50);
}
